package yycore

import chisel3._
import chisel3.util._
import chisel3.util.experimental.BoringUtils
import common.Constants._

object MOUOpType {
  def fence  = "b00".U
  def fencei = "b01".U
  def sfence_vma = "b10".U
}

class MOUReqBundle extends Bundle {
  val fun = UInt(4.W)
  val pc = UInt(AddrBits.W)
}

/**
 * Memory Order Unit
 */
class MOU extends Module {
  val io = IO(new Bundle() {
    val req = Flipped(ValidIO(new MOUReqBundle))
    val redirect = new RedirectIO
  })
  val (valid, fun) = (io.req.valid, io.req.bits.fun)

  val flushICache = valid && (fun === MOUOpType.fencei)
  BoringUtils.addSource(flushICache, "MOUFencei")

  io.redirect.target := io.req.bits.pc + 4.U
  io.redirect.valid := valid
}
